﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using UnityEngine;

namespace HDJ.Framework.Core
{
    public class TableTypeSupportController: Singleton<TableTypeSupportController>
    {
        private  Dictionary<Type, TableTypeSupportBase> baseTypeSupports = new Dictionary<Type, TableTypeSupportBase>();

        private List<TableTypeSupprotObjectBase> objectTypeSupports = new List<TableTypeSupprotObjectBase>();

        public  TableTypeSupportController()
        {
            {
                Type[] types = ReflectionUtils.GetChildTypes(typeof(TableTypeSupportBase));

                foreach (var t in types)
                {
                    TableTypeSupportBase instance = (TableTypeSupportBase)Activator.CreateInstance(t);
                    baseTypeSupports.Add(instance.TableType, instance);
                }
            }
            {
                Type[] types = ReflectionUtils.GetChildTypes(typeof(TableTypeSupprotObjectBase));

                foreach (var t in types)
                {
                    TableTypeSupprotObjectBase instance = (TableTypeSupprotObjectBase)Activator.CreateInstance(t,new object[] { baseTypeSupports });
                    objectTypeSupports.Add( instance);
                }
            }
        }
        public Type GetTableType(TableTypeData typeData)
        {
            Debug.Log("GetTableType:" + typeData);
            string typeCategory = null;
            if (!string.IsNullOrEmpty(typeData.typeCategory))
                 typeCategory= typeData.typeCategory.ToLower();

            if (!string.IsNullOrEmpty(typeCategory))
            {
                foreach (var item in objectTypeSupports)
                {
                    if (item.TypeCategory.Contains(typeCategory))
                    {
                        return item.GetTableType(typeData.dataType);
                    }
                }
                foreach (var item in baseTypeSupports.Values)
                {
                    if (item.TypeCategory.Contains(typeCategory)&& item.TypeStringSupport.Contains(typeData.dataType))
                    {
                        return item.TableType;
                    }
                }
            }
            else
            {
                foreach (var item in baseTypeSupports.Values)
                {
                    if (item.TypeStringSupport.Contains(typeData.dataType))
                    {
                        return item.TableType;
                    }
                }
            }


            Debug.LogError("不支持的类型typeCategory:" + typeData.typeCategory + " =>dataType:" + typeData.dataType);
            return null;

        }
        public TableTypeData GetTypeData(Type type,string tag)
        {
            if(type == null)
            {
                Debug.LogError("类型不能为null");
                return null;
            }
            string dataType = null;
            string typeCategory = null;
            if (baseTypeSupports.ContainsKey(type))
            {

               dataType = baseTypeSupports[type].TypeStringSupport[0];
                typeCategory = baseTypeSupports[type].TypeCategory[0];
            }
            else if (type.IsArray)
            {
                foreach (var item in objectTypeSupports)
                {
                    if (item.IsArray)
                    {
                        Type elementType = type.GetElementType();
                        if (baseTypeSupports.ContainsKey(elementType))
                        {
                          string  basedataType = baseTypeSupports[elementType].TypeStringSupport[0];
                            dataType = type.FullName.Replace(elementType.FullName, basedataType);
                        }
                        else
                        {
                            dataType = type.FullName;
                        }
                        typeCategory = item.TypeCategory[0];

                        break;
                    }
                }
            }
            else if (type.IsEnum )
            {
                //枚举
                dataType = type.FullName;
                foreach (var item in objectTypeSupports)
                {
                    if (item.IsEnum)
                    {
                        typeCategory = item.TypeCategory[0];

                        break;
                    }
                }
            }else if(type.IsClass || (!type.IsPrimitive && type.IsValueType))
            {
                dataType = type.FullName;
                foreach (var item in objectTypeSupports)
                {
                    if (item.IsObject)
                    {
                        typeCategory = item.TypeCategory[0];

                        break;
                    }
                }
            }
            else
            {
                Debug.LogError("不支持的类型：" + type.FullName);
                return null;
            }
            return new TableTypeData(dataType, typeCategory, tag);
        }
        public bool IsSupportType(Type type)
        {
            if (type == null)
            {
                Debug.LogError("类型不能为null");
                return false;
            }
            string dataType = null;
            string typeCategory = null;
            if (baseTypeSupports.ContainsKey(type))
            {
            }
            else if (type.IsArray)
            {
                foreach (var item in objectTypeSupports)
                {
                    if (item.IsArray)
                    {
                        Type elementType = type.GetElementType();
                        if (baseTypeSupports.ContainsKey(elementType))
                        {
                            string basedataType = baseTypeSupports[elementType].TypeStringSupport[0];
                            dataType = type.FullName.Replace(elementType.FullName, basedataType);
                        }
                        else
                        {
                            dataType = type.FullName;
                        }
                        typeCategory = item.TypeCategory[0];

                        break;
                    }
                }
            }
            else if (type.IsEnum)
            {
                //枚举
                dataType = type.FullName;
                foreach (var item in objectTypeSupports)
                {
                    if (item.IsEnum)
                    {
                        typeCategory = item.TypeCategory[0];

                        break;
                    }
                }
            }
            else if (type.IsClass || (!type.IsPrimitive && type.IsValueType))
            {
                dataType = type.FullName;
                foreach (var item in objectTypeSupports)
                {
                    if (item.IsObject)
                    {
                        typeCategory = item.TypeCategory[0];

                        break;
                    }
                }
            }
            else
            {
                return false;
            }
            return true;
        }

        public object GetDefultData(Type type)
        {
            object value = null;


            if (baseTypeSupports.ContainsKey(type))
            {
                TableTypeSupportBase instance = baseTypeSupports[type];
                value = instance.GetTypeDefultValue();
            }
            else if (type.IsEnum)
            {
                foreach (var item in objectTypeSupports)
                {
                    if (item.IsEnum)
                    {
                        value = item.GetTypeDefultValue(type);
                        break;
                    }
                }

            }
            else if (type.IsArray)
            {
                foreach (var item in objectTypeSupports)
                {
                    if (item.IsArray)
                    {
                        value = item.GetTypeDefultValue(type);
                        break;
                    }
                }
            }
            else if (type.IsClass || (!type.IsPrimitive && type.IsValueType))
            {
                foreach (var item in objectTypeSupports)
                {
                    if (item.IsObject)
                    {
                        value = item.GetTypeDefultValue(type);
                        break;
                    }
                }
            }
            return value;
        }

        public  object TableStringData2Value(Type type, string data)
        {
            object value = null;

           
             if (baseTypeSupports.ContainsKey(type))
            {
                TableTypeSupportBase instance = baseTypeSupports[type];
                value = instance.TableStringData2Value(data);
            }
            else if (type.IsEnum)
            {
                foreach (var item in objectTypeSupports)
                {
                    if (item.IsEnum)
                    {
                        value = item.TableStringData2Value(type, data);
                        break;
                    }
                }
               
            }
            else if (type.IsArray)
            {
                foreach (var item in objectTypeSupports)
                {
                    if (item.IsArray)
                    {
                        value = item.TableStringData2Value(type, data);
                        break;
                    }
                }
            }
             else if(type.IsClass || (!type.IsPrimitive && type.IsValueType))
            {
                foreach (var item in objectTypeSupports)
                {
                    if (item.IsObject)
                    {
                        value = item.TableStringData2Value(type, data);
                        break;
                    }
                }
            }
            return value;
        }

        public  string ObjectValue2TableString(object value)
        {
            if (null == value)
                return "";

            Type type = value.GetType();
            string result = "";
             if (baseTypeSupports.ContainsKey(type))
            {
                TableTypeSupportBase instance = baseTypeSupports[type];
                result = instance.ObjectValue2TableString(value);
            }
            else if (type.IsEnum)
            {
                foreach (var item in objectTypeSupports)
                {
                    if (item.IsEnum)
                    {
                        result = item.ObjectValue2TableString(value);
                        break;
                    }
                }

            }
            else if (type.IsArray)
            {
                foreach (var item in objectTypeSupports)
                {
                    if (item.IsArray)
                    {
                        result = item.ObjectValue2TableString(value);
                        break;
                    }
                }
            }
            else if (type.IsClass || (!type.IsPrimitive && type.IsValueType))
            {
                foreach (var item in objectTypeSupports)
                {
                    if (item.IsObject)
                    {
                        result = item.ObjectValue2TableString(value);
                        break;
                    }
                }
            }
            return result;
        }
    }
}
